﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.IO.Ports;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace Demo_Socket_Client
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            mySocketInit();
        }

        //初始化客户端类
        private CsMySocketClient mySocketClient = new CsMySocketClient();
        private CsMySocketClient.SocketClientIP ClientIP;

        //初始化服务器IP和端口号+绑定消息接收事件
        private void mySocketInit()
        {
            try
            {
                mySocketClient.ReceEvent += ReceServiceDataClick;
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine(ex.Message);
            }
        }

        private bool ReceTCP(string strIn)
        {
            var strCompare = strIn.Split('=');
            if (strCompare.Count() > 1)
            {
                if (strCompare[0] == "#TCP000")
                {
                    T_LocalEndPoint.Text = mySocketClient.LocalEndPoint();
                    T_RemoteEndPoint.Text = strCompare[1];
                    return false;
                }
                if (strCompare[0] == "#TCP404")
                {
                    T_LocalEndPoint.Text = "已断开";
                    T_RemoteEndPoint.Text = "已断开";
                    return false;
                }
                if (strCompare[1] == "")
                {
                    return false;
                }
            }
            return true;
        }

        private void ReceServiceDataClick(string strIn)
        {
            System.Windows.Application.Current.Dispatcher.BeginInvoke((Action)delegate ()
            {
                if (!ReceTCP(strIn))
                    return;
                if (false)
                    TxRece.Text += strIn;
                else
                    TxRece.Text += strIn + "\r\n";
            });
        }

        private void BtTxSend_Click(object sender, RoutedEventArgs e) => mySocketClient.SendData(TxSend.Text);

        private void BtClearTxRece_Click(object sender, RoutedEventArgs e) => TxRece.Text = string.Empty;

        private void BtBreak_Click(object sender, RoutedEventArgs e) => mySocketClient.SocketBreak();

        private void BtConnect_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                ClientIP.strIpAddress = ViewIP.Text;
                ClientIP.nPort = int.Parse(ViewPoint.Text);

                mySocketClient.SocketConnect(ClientIP);
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine(ex.Message);

            }

        }

    }

    public class CsMySocketClient
    {
        /// <summary>
        /// 作者:WangJunLiang || Wechat:Joronwongx
        /// </summary>
        public CsMySocketClient()//需要初始化
        {
            BackgroundWorker = new BackgroundWorker();
            BackgroundWorker.DoWork += ReceServiceDataClick;
            BackgroundWorker.WorkerSupportsCancellation = true; //允许取消
        }

        private Socket tcpClient = null;
        private BackgroundWorker BackgroundWorker = null;

        public delegate void ReceServiceData(string strRece);
        public event ReceServiceData ReceEvent;

        public struct SocketClientIP
        {
            public string strIpAddress;
            public int nPort;
        };

        //内容监听
        private void ReceServiceDataClick(object sender, DoWorkEventArgs e)
        {
            while (!BackgroundWorker.CancellationPending)
            {
                try
                {
                    if (tcpClient.Poll(10, SelectMode.SelectRead))
                    {
                        BackgroundWorker.CancelAsync();//停止执行DoWork
                        break;
                    }
                    byte[] data = new byte[1024];  //传递一个byte数组，用于接收数据。length表示接收了多少字节的数据
                    int length = tcpClient.Receive(data);
                    string strOut = Encoding.UTF8.GetString(data, 0, length);//只将接收到的数据进行转化 =========阻塞======
                    ReceEvent(string.Format("[{0}]-{1}", tcpClient.RemoteEndPoint.ToString(), strOut));
                }
                catch (Exception ex)
                {
                    System.Diagnostics.Debug.WriteLine(ex.Message);
                    ReceEvent(string.Format("[{0}]-{1}", tcpClient.RemoteEndPoint.ToString(), ex.Message));
                    tcpClient.Close();
                    tcpClient = null;
                }
            }
            ReceEvent(string.Format("#TCP404-{0}", tcpClient.RemoteEndPoint.ToString()));
            tcpClient.Shutdown(SocketShutdown.Both);
            tcpClient.Close();
            tcpClient = null;
        }

        //本地连接Point
        public string LocalEndPoint() => tcpClient.LocalEndPoint.ToString();

        //远程连接Point
        public string RemoteEndPoint() => tcpClient.RemoteEndPoint.ToString();

        //创建连接
        public bool SocketConnect(SocketClientIP ClientIP)
        {
            try
            {
                if (tcpClient == null || tcpClient.Poll(10, SelectMode.SelectRead))
                {
                    tcpClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                    EndPoint point = new IPEndPoint(IPAddress.Parse(ClientIP.strIpAddress), ClientIP.nPort);
                    tcpClient.Connect(point);//通过IP和端口号来定位一个所要连接的服务器端
                    BackgroundWorker.RunWorkerAsync();//开始执行DoWork
                    ReceEvent(string.Format("#TCP000-{0}", tcpClient.RemoteEndPoint.ToString()));
                    return true;
                }
                return false;
            }
            catch (System.Exception ex)
            {
                System.Diagnostics.Debug.WriteLine(ex.Message);
                tcpClient = null;
                return false;
            }
        }

        //断开连接
        public bool SocketBreak()
        {
            try
            {
                if (tcpClient != null && tcpClient.Connected)
                {
                    tcpClient.Shutdown(SocketShutdown.Both);
                    return true;
                }
                return false;
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine(ex.Message);
                return false;
            }
        }

        //发送内容
        public void SendData(string strIn)
        {
            try
            {
                if (tcpClient != null && tcpClient.Connected)
                    tcpClient.Send(Encoding.UTF8.GetBytes(strIn)); //将字符串转化为字节数组，然后发送到服务器端
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine(ex.Message);
            }
        }
    }
}
